package org.pine.dictionary.service.impl;

import cn.hutool.core.util.IdUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.read.listener.PageReadListener;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.baomidou.mybatisplus.core.metadata.IPage;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.pine.dictionary.bean.PageRequest;
import org.pine.dictionary.bean.PageResponse;
import org.pine.dictionary.bean.excel.DictionaryDetailImportDto;
import org.pine.dictionary.bean.request.DictionaryDetailQueryRequest;
import org.pine.dictionary.bean.request.DictionaryDetailSaveRequest;
import org.pine.dictionary.bean.response.DictionaryDetailQueryResponse;
import org.pine.dictionary.common.StatusEnum;
import org.pine.dictionary.service.IDictionaryDetailService;
import org.pine.dictionary.service.bo.DictionaryDetailBo;
import org.pine.dictionary.service.manager.DictionaryDetailManager;
import org.pine.dictionary.util.PageUtil;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * <p>
 * 字典明细表 服务实现类
 * </p>
 *
 * @author pine
 * @since 2024-05-15
 */
@Slf4j
@Service
public class DictionaryDetailServiceImpl implements IDictionaryDetailService {

    @Resource
    private DictionaryDetailManager dictionaryDetailManager;

    /**
     * 新增
     *
     * @param request 请求
     */
    @Override
    public void insert(DictionaryDetailSaveRequest request) {
        // 请求体转换为业务对象
        DictionaryDetailBo dictionaryDetailBo = transformToEntity(request);
        // 生成字典明细ID
        dictionaryDetailBo.setDictionaryDetailId(IdUtil.getSnowflake().nextIdStr());
        // 校验插入数据
        checkForInsert(dictionaryDetailBo);

        // 数据落库
        dictionaryDetailManager.save(dictionaryDetailBo);
    }

    /**
     * 按业务ID更新
     *
     * @param request 请求
     */
    @Override
    public void update(DictionaryDetailSaveRequest request) {
        // 查询原字典明细数据
        DictionaryDetailBo oldDictionaryDetailBo = dictionaryDetailManager.getOne(request.getDictionaryId());
        if (Objects.isNull(oldDictionaryDetailBo)) {
            return;
        }

        // 请求体转换为业务对象
        DictionaryDetailBo dictionaryDetailBo = transformToEntity(request);
        // 校验更新数据
        checkForUpdate(dictionaryDetailBo);
        // 更新时不更新编码
        dictionaryDetailBo.setDictionaryValueCode(null);

        // 数据落库
        dictionaryDetailManager.updateById(dictionaryDetailBo);
    }

    /**
     * 按业务ID列表批量删除
     *
     * @param idList id 列表
     */
    @Override
    public void delete(List<String> idList) {
        dictionaryDetailManager.removeBatchByIds(idList);
    }

    /**
     * 按业务ID查信息
     *
     * @param id 业务id
     * @return 响应
     */
    @Override
    public DictionaryDetailQueryResponse getDetail(String id) {
        DictionaryDetailBo entity = dictionaryDetailManager.getOne(id);
        return transformToResponse(entity);
    }

    /**
     * 查询信息（分页）
     *
     * @param request 请求
     * @return PageResponse 响应
     */
    @Override
    public PageResponse<DictionaryDetailQueryResponse> list(PageRequest<DictionaryDetailQueryRequest> request) {

        // 分页查询字典信息
        IPage<DictionaryDetailBo> dictionaryDetailPage = dictionaryDetailManager.page(transformToQuery(request));

        // 组装响应结果
        return PageUtil.convertPage(dictionaryDetailPage, dictionaryDetailPage.getRecords().stream().map(this::transformToResponse).collect(Collectors.toList()));
    }

    /**
     * 启用
     *
     * @param idList id 列表
     */
    @Override
    public void enable(List<String> idList) {
        dictionaryDetailManager.changeStatusByDictionaryDetailIds(idList, StatusEnum.ENABLE);
    }

    /**
     * 禁用
     *
     * @param idList id 列表
     */
    @Override
    public void disable(List<String> idList) {
        dictionaryDetailManager.changeStatusByDictionaryDetailIds(idList, StatusEnum.DISABLE);
    }

    /**
     * 导入
     *
     * @param file 表格文件
     */
    @Override
    public void importExcel(MultipartFile file) {
        try {
            EasyExcel.read(file.getInputStream(), DictionaryDetailImportDto.class, new PageReadListener<DictionaryDetailImportDto>(importDtos -> {
                // todo 数据校验

                // 数据转换
                List<DictionaryDetailBo> dictionaryDetailBos = transformToEntities(importDtos);

                for (DictionaryDetailBo dictionaryDetailBo : dictionaryDetailBos) {
                    // 数据校验
                    checkForInsert(dictionaryDetailBo);

                    // 设置字典明细ID
                    dictionaryDetailBo.setDictionaryDetailId(IdUtil.getSnowflake().nextIdStr());
                }

                // 保存到数据库
                int insertNums = dictionaryDetailManager.saveBatch(dictionaryDetailBos);
                log.info("插入数据条数：{}", insertNums);
            })).sheet().doRead();
        } catch (IOException e) {
            log.warn("上传文件异常 {}", e.getLocalizedMessage(), e);
            throw new RuntimeException(e);
        }
    }

    /**
     * 获取导入模版
     *
     * @param response servlet响应对象
     */
    @Override
    public void importTpl(HttpServletResponse response) {
        try {
            // 设置相应格式
            response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
            response.setCharacterEncoding("utf-8");

            // URLEncoder.encode 可以防止中文乱码
            String filename = "字典明细_导入模版_" + LocalDateTime.now();
            filename = URLEncoder.encode(filename, StandardCharsets.UTF_8).replaceAll("\\+", "%20");
            response.setHeader("Content-disposition", "attachment;filename*=" + filename + ".xlsx");
            try (ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream(), DictionaryDetailImportDto.class).autoCloseStream(false).build()) {
                WriteSheet writeSheet = EasyExcel.writerSheet("sheet").build();
                excelWriter.write(Collections.emptyList(), writeSheet);
            }
        } catch (Exception e) {
            log.warn("导出模版异常 {}", e.getLocalizedMessage(), e);
            throw new RuntimeException(e);
        }
    }

    /**
     * 导出
     *
     * @param response servlet响应对象
     * @param request  请求参数
     */
    @Override
    public void export(HttpServletResponse response, DictionaryDetailQueryRequest request) throws IOException {
    }
}
